package com.deli.pagingforjava;

import androidx.paging.PagingState;
import androidx.paging.rxjava2.RxPagingSource;

import com.deli.pagingforjava.bean.BaseItemBean;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

import io.reactivex.Single;
import io.reactivex.SingleEmitter;
import io.reactivex.schedulers.Schedulers;

/**
 * @Author: QDL
 * @CreateDate: 2021/4/23 10:20
 */
public class SimplePagingSource<T, V extends BaseItemBean> extends RxPagingSource<T, V> {
    LoadParams<T> params;
    PagingSourceRequest<T, V> sourceRequest;

    public SimplePagingSource(PagingSourceRequest<T, V> sourceRequest) {
        this.sourceRequest = sourceRequest;
    }

    @NotNull
    @Override
    public Single<LoadResult<T, V>> loadSingle(@NotNull LoadParams<T> loadParams) {
        params = loadParams;
        return request(loadParams, sourceRequest)
                .subscribeOn(Schedulers.io())
                .map(this::loadResult)
                .onErrorReturn(LoadResult.Error::new);
    }

    private LoadResult<T, V> loadResult(List<V> list) {

        T nextKey = sourceRequest.getNextPageKey(params, list);
        return new LoadResult.Page<>(
                list,
                null,
                nextKey,
                LoadResult.Page.COUNT_UNDEFINED,
                LoadResult.Page.COUNT_UNDEFINED);
    }


    private Single<List<V>> request(final LoadParams<T> loadParams, PagingSourceRequest<T, V> callBack) {
        return Single.create(emitter -> {
            callBack.handleRequest(emitter, loadParams);
        });
    }


    @Nullable
    @Override
    public T getRefreshKey(@NotNull PagingState<T, V> pagingState) {
        return null;
    }

    public interface PagingSourceRequest<T, V extends BaseItemBean> {
        /**
         * 处理网络请求（暴露给外部调用）
         *
         * @param emitter 把请求结果通过emitter返回给pagingSource
         * @param params  加载参数（分页相关的）
         */
        public void handleRequest(SingleEmitter<List<V>> emitter, LoadParams<T> params);

        /**
         * 下一页分页参数
         *
         * @param params 加载参数
         * @param list   返回的数据列表
         * @return 下一页分页参数
         */
        public T getNextPageKey(LoadParams<T> params, List<V> list);
    }
}
